<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 转换前：
    let source = [{
      id: 1,
      pid: 0,
      name: 'body'
    }, {
      id: 2,
      pid: 1,
      name: 'title'
    }, {
      id: 3,
      pid: 2,
      name: 'div'
    }, {
      id: 4,
      pid: 2,
      name: 'div'
    }
    ]
    // 转换为: 
    let tree = [{
      id: 1,
      pid: 0,
      name: 'body',
      children: [{
        id: 2,
        pid: 1,
        name: 'title',
        children: [{
          id: 3,
          pid: 1,
          name: 'div'
        }]
      }]
    }]

    function jsonToTree (data) {
      // 初始化结果数组 判断数据的格式
      let result = []
      if (!Array.isArray(data)) {
        return data // 如果不是数组 就直接返回
      }
      // 使用map对当前对象的id与当前对象对应储存起来
      let map = {}
      data.forEach(item => {
        map[item.id] = item
      })
      data.forEach(item => { // 遍历每一个值 找到他的父节点
        let parent = map[item.pid] // 根据pid找到父节点
        if (parent) { // 如果父节点存在的话
          (parent.children || (parent.children = [])).push(item) // 看父节点的children属性存在不 如果存在 就pushitem 如果不存在就初始化 然后push
        } else {
          result.push(item) // 如果父节点不存在就push 这个item
        }
      })
      return result
    }
    function jsontotree (data) {
      let result = []
      if (!Array.isArray(data)) {
        return data
      }
      let map = {}
      data.forEach(item => {
        map[item.id] = item
      })
      data.forEach(item => {
        let parent = map[item.pid]
        if (parent) {
          (parent.children || (parent.children = [])).push(item)
        } else {
          result.push(item)
        }
      })
      return result
    }
    let newTree = jsonToTree(source)
    // document.write(JSON.stringify(jsontotree(source)))
    function treeToArr (tree) {
      let result = []
      tree.forEach((item) => {
        let newitem = {}
        for (let key in item) {
          if (key !== 'children') {
            newitem[key] = item[key]
          }
        }
        result.push(newitem)
        if (item.children) {
          // item.children.forEach((smallitem) => {
          //   let smallResult = treeToArr()
          //   result.push(...smallResult)
          // })
          let smallResult = treeToArr(item.children)
          result.push(...smallResult)
        }
      })
      return result
    }
    console.log(treeToArr(newTree))
  </script>
</body>

</html>